<?php

namespace services\marketing;

use common\helpers\ArrayHelper;
use common\models\common\TrueDeleteLog;
use common\models\patient\User;
use services\common\CommonService;
use Yii;
use common\components\Service;
use common\models\marketing\SourceChannel;

/**
 * Class SourceChannelService
 * @package services\marketing
 */
class SourceChannelService extends Service
{
    /**
     * 根据ID查找信息
     *
     * @param int $id
     * @return SourceChannel|null
     */
    public function findById(int $id = 0): ?SourceChannel
    {
        return SourceChannel::find()->where(['id' => $id])->one();
    }

    /**
     * 查找信息
     *
     * @param array $condition
     * @return SourceChannel|null
     */
    public function findInfo(array $condition = []): ?SourceChannel
    {
        $query = SourceChannel::find();

//        isset($condition['project_id']) && $query->andWhere(['project_id' => $condition['project_id']]);
//        isset($condition['name']) && $query->andWhere(['name' => $condition['name']]);
//        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);

        return $query->one();
    }

    /**
     * 查找列表
     *
     * @param array $condition
     * @return array|\yii\db\ActiveRecord[]
     */
    public function findList(array $condition = [])
    {
        $query = SourceChannel::find();

        // select
        isset($condition['select']) && $query->select($condition['select']);

        // condition
        isset($condition['project_id']) && $query->andWhere(['project_id' => $condition['project_id']]);
        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);
        isset($condition['pid']) && $query->andWhere(['pid' => $condition['pid']]);

        return $query->asArray()->all();
    }

    /**
     * 来源渠道列表
     *
     * @param $page
     * @param $pageSize
     * @return array
     */
    public function getList($page, $pageSize, $projectId)
    {
        $query = SourceChannel::find()->select('id, source_name, pid, sort, status, is_inhibit_delete')
            ->where([
                'status' => [SourceChannel::STATUS_INVALID, SourceChannel::STATUS_ENABLE],
                'pid' => 0,
                'project_id' => $projectId
            ]);

        // 总数
        $total = $query->count();

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query
            ->orderBy(['status' => SORT_DESC, 'sort' => SORT_ASC])
            ->asArray()
            ->all();

        // 获取不是一级的来源渠道
        $childSource = SourceChannel::find()
            ->select('id, source_name, pid, sort, status, is_inhibit_delete')
            ->where(['status' => [SourceChannel::STATUS_INVALID, SourceChannel::STATUS_ENABLE]])
            ->andWhere(['>', 'pid', 0])
            ->orderBy(['status' => SORT_DESC, 'sort' => SORT_ASC])
            ->asArray()
            ->all();

        // 整合数据
        $childList = [];
        foreach ($childSource as $cs) {
            $childList[$cs['pid']][] = $cs;
        }

        foreach ($list as &$val) {
            if (isset($childList[$val['id']])) {
                $val['children'] = $childList[$val['id']];
            }
        }

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];
    }

    /**
     * 新增来源渠道
     *
     * @param $params
     * @return array
     * @throws \Exception
     */
    public function create($params)
    {
        if (isset($params['source_name']) && !$params['source_name']) {
            return ['code' => 422, 'message' => '来源名称不能为空'];
        }
        $sourceName = explode(',', Yii::$app->services->bodyParts->strFormat($params['source_name']));
        $exists = $this->checkName([
            'source_name' => $sourceName,
            'project_id' => $params['project_id'],
            'status' => [SourceChannel::STATUS_ENABLE, SourceChannel::STATUS_INVALID]
        ]);
        if ($exists) {
            return ['code' => 422, 'message' => '来源渠道名称已存在'];
        }

        $transaction = Yii::$app->db->beginTransaction();
        try {
            $addList = [];
            if ($sourceName) {
                foreach ($sourceName as $k => $v) {
                    $add['source_name'] = $v;
                    $add['pid'] = $params['pid'];
                    $add['project_id'] = $params['project_id'];
                    $add['status'] = isset($params['status']) && $params['status'] ? $params['status'] : 1;
                    $add['sort'] = $params['sort'] + $k;
                    $add['is_inhibit_delete'] = SourceChannel::INHIBIT_DELETE;
                    $add['operation_id'] = $params['member_id'];
                    $add['created_time'] = time();
                    $add['updated_time'] = time();
                    $addList[] = $add;
                }
                Yii::$app->db->createCommand()
                    ->batchInsert(SourceChannel::tableName(),
                        ['source_name', 'pid', 'project_id', 'status', 'sort', 'is_inhibit_delete', 'operation_id', 'created_at', 'updated_at'],
                        $addList)
                    ->execute();
            }
            $transaction->commit();

            // 添加缓存
            CommonService::baseRedis('source_channel', 2);

            return ['code' => 200, 'message' => '新增成功'];
        } catch (\Exception $exception) {
            $transaction->rollBack();
            throw new \Exception($exception->getMessage(), 500);
        }
    }

    /**
     * 获取来源渠道的排序
     *
     * @param $pid
     * @return int|string
     */
    public function getNewSort($pid)
    {
        $count = SourceChannel::find()->where(['pid' => $pid])->count();
        return $count + 1;
    }

    /**
     * 判断是否存在
     *
     * @param $where
     * @return bool
     */
    public function checkName($where)
    {
        return SourceChannel::find()->where($where)->exists();
    }

    /**
     * 编辑状态
     *
     * @param int $id
     * @param int $status
     * @return array
     * @throws \Exception
     */
    public function updateStatus(int $id, int $status)
    {
        $exists = $this->checkName(['id' => $id]);
        if (!$exists) {
            return ['code' => 422, 'message' => '该来源渠道不存在'];
        }

        $transaction = Yii::$app->db->beginTransaction();
        try {
            $haveChild = $this->checkName(['pid' => $id, 'status' => [SourceChannel::STATUS_ENABLE, SourceChannel::STATUS_INVALID]]);
            if ($haveChild) {
                SourceChannel::updateAll(['status' => $status], ['pid' => $id]);
            }
            $data = SourceChannel::updateAll(['status' => $status], ['id' => $id]);
            if (!$data) {
                return ['code' => 422, 'message' => '修改失败'];
            }
            $transaction->commit();

            // 添加缓存
            CommonService::baseRedis('source_channel', 2);

            return ['code' => 200, 'message' => '修改成功'];
        } catch (\Exception $exception) {
            $transaction->rollBack();
            throw new \Exception($exception->getMessage(), 500);
        }
    }

    /**
     * 编辑来源渠道
     *
     * @param array $params
     * @return array
     * @throws \Exception
     */
    public function update(array $params)
    {
        $exists = $this->checkName(['id' => $params['id']]);
        if (!$exists) {
            return ['code' => 422, 'message' => '数据不存在'];
        }

        $model = SourceChannel::findOne($params['id']);
        $sourceChannelIs = SourceChannel::findOne(
            [
                'source_name' => $params['source_name'],
                'project_id' => $params['project_id'],
                'status' => [SourceChannel::STATUS_ENABLE, SourceChannel::STATUS_INVALID],
            ]
        );
        if ($sourceChannelIs && $sourceChannelIs->id != $params['id']) {
            return ['code' => 422, 'message' => '该来源渠道名称已存在'];
        }

        if ($sourceChannelIs && $params['pid'] == $sourceChannelIs->id) {
            return ['code' => 422, 'message' => '父节点不能是自己'];
        }

        // 是否有子集，有子集不能选择pid
        $haveChild = $this->checkName(['pid' => $model->id, 'status' => [SourceChannel::STATUS_ENABLE, SourceChannel::STATUS_INVALID]]);
        if ($haveChild && $params['pid'] > 0) {
            return ['code' => 422, 'message' => '来源渠道有子级不能选择父节点'];
        }

        $transaction = Yii::$app->db->beginTransaction();
        try {
            if ($haveChild) {
                SourceChannel::updateAll(['status' => $params['status']], ['pid' => $sourceChannelIs->id]);
            }
            $model->source_name = $params['source_name'];
            $model->project_id = $params['project_id'];
            $model->pid = $params['pid'];
            $model->sort = $params['sort'];
            $model->status = $params['status'];
            $model->operation_id = $params['member_id'];
            if (!$model->save()) {
                return ['code' => 422, 'message' => '修改失败'];
            }
            $transaction->commit();

            // 添加缓存
            CommonService::baseRedis('source_channel', 2);

            return ['code' => 200, 'message' => '修改成功'];
        } catch (\Exception $exception) {
            $transaction->rollBack();
            throw new \Exception($exception->getMessage(), 500);
        }
    }

    /**
     * 删除来源渠道
     *
     * @param int $id
     * @return array
     */
    public function delete(int $id)
    {
        $exists = $this->checkName(['id' => $id]);
        if (!$exists) {
            return ['code' => 422, 'message' => '该来源渠道不存在'];
        }
        $data = SourceChannel::updateAll(['status' => SourceChannel::STATUS_DELETE], ['id' => $id]);
        if (!$data) {
            return ['code' => 422, 'message' => '删除失败'];
        }

        // 添加缓存
        CommonService::baseRedis('source_channel', 2);

        return ['code' => 200, 'message' => '删除成功'];
    }

    /**
     * @apiName  真删除 ,渠道真删除->patient_user 表清空 渠道信息
     * @apiGroup
     * @apiParam {Number}
     * @apiParam {String}
     * @author loujie
     * @param int $id
     * @return array
     * @throws \Exception
     */
    public function trueDelete(int $id)
    {
        $channelArray = SourceChannel::find()
            ->select('id, source_name, pid, project_id')
            ->where(['id' => $id])
            ->asArray()
            ->all();

        if (!$channelArray) {
            return ['code' => 422, 'message' => '该效果类型不存在'];
        }

        $transaction = Yii::$app->db->beginTransaction();
        try {
            $member = Yii::$app->user->identity->member;

            // 如果是
            if ($channelArray[0]['pid'] == 0) {
                // 需要筛选全部子集批量删除
                $childSource = SourceChannel::find()
                    ->select('id, source_name, pid, project_id')
                    ->where(['project_id' => $channelArray[0]['project_id']])
                    ->andWhere(['>', 'pid', 0])
                    ->asArray()
                    ->all();

              $childSourceArray = ArrayHelper::getChilds($childSource,$id);

              foreach ($childSourceArray as $value) {
                  $channelArray[] = $value;
              }

            }

            $insertData = [];

            foreach ($channelArray as $data) {
                $insertData[] = [
                    'project_id' => $data['project_id'],
                    'delete_id' => $data['id'],
                    'delete_name' => $data['source_name'],
                    'delete_table' => SourceChannel::tableName(),
                    'effect_table' => '【' . User::tableName() . '（source_channel_id）】',
                    'operator_id' => $member->id,
                    'operator_name' => $member->realname,
                    'created_at' => time(),
                    'updated_at' => time()
                ];
            }

            $ids = array_column($channelArray,'id');
            // 删除效果类型
            $data = SourceChannel::deleteAll(['id' => $ids]);
            // 清空效果类型
            User::updateAll(['updated_at' => time(), 'source_channel_id' => 0],['source_channel_id' => $ids]);
            // 记录修改记录
            Yii::$app->db->createCommand()->batchInsert(TrueDeleteLog::tableName(),[
                'project_id', 'delete_id', 'delete_name', 'delete_table', 'effect_table', 'operator_id', 'operator_name', 'created_at', 'updated_at'
            ],$insertData);

            $transaction->commit();

        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }

        if (!$data) {
            return ['code' => 422, 'message' => '删除失败'];
        }

        // 添加缓存
        CommonService::baseRedis('source_channel', 2);

        return ['code' => 200, 'message' => '删除成功'];
    }


    /**
     * 获取父来源渠道
     *
     * @return array|\yii\db\ActiveRecord[]
     */
    public function getParentSourceChannel($projectId)
    {
        return SourceChannel::find()->select('id, source_name')->where([
            'status' => SourceChannel::STATUS_ENABLE,
            'pid' => 0,
            'project_id' => $projectId
        ])->asArray()->all();
    }

    /**
     * @param $id
     * @return array
     */
    public static function getSourceIdAndPidListById($id): array
    {
        return SourceChannel::find()
            ->where([
                'or',
                ['id' => $id],
                ['pid' => $id],
            ])
            ->asArray()
            ->all();
    }
}